import type {
  specInfoParamList,
  specKeyParamList,
  specValue,
} from '@/types/shop'
import { ref } from 'vue'
import { buildUUID } from '@/utils/uuid'
import { cloneDeep, pullAll } from 'lodash-es'
import { computed } from '@vue/reactivity'
export default function () {
  const tableDatas = ref<Partial<specInfoParamList[]>>([])
  /**
   * 单元格合并字典
   * key  rowIndex-columnIndex
   * value [number, number]
   */
  const spanMergeDic = ref({})

  interface sectionType {
    text: string
    value: specValue[]
  }
  const sectionData = ref<Partial<sectionType[]>>([
    { text: '', value: [] },
    { text: '', value: [] },
    { text: '', value: [] },
  ])
  // TODO 上级为空不能添加，下级还有不能删完
  const sectionLevel = computed(() => {
    let level = 0
    for (let index = 1; index < sectionData.value.length; index++) {
      if (
        sectionData.value.length > index &&
        // @ts-ignore：无法被执行的代码的错误
        sectionData.value[index].value.length > 0
      ) {
        level = index
      }
    }
    return level
  })
  /**
   * 1. 格式化生成合并索引
   * 2. 有UUID不再分配新id1
   */
  function initDatas(data: specInfoParamList[]) {
    // clearDatas()
    const dic1 = {}
    const dic2 = {}
    const dic3 = {}

    const uuidDic = { specUUIDS_0: {}, specUUIDS_1: {}, specUUIDS_2: {} }
    // TODO 1 data 进来需要先排一次序列。把相近的排到一起
    const sortData = sortWithDatas(data, 0, 2)
    sortData?.forEach((item: specInfoParamList, index) => {
      const specKeyParamList = item.specKeyParamList
      specKeyParamList.forEach((item, index) => {
        // @ts-ignore：无法被执行的代码的错误
        if (!uuidDic['specUUIDS_' + index][item.specValue.value]) {
          const uuid = buildUUID()
          // @ts-ignore：无法被执行的代码的错误
          uuidDic['specUUIDS_' + index][item.specValue.value] = uuid
          // @ts-ignore：无法被执行的代码的错误
          item.specValue.uuid = uuid
        } else {
          // @ts-ignore：无法被执行的代码的错误
          item.specValue.uuid =
            // @ts-ignore：无法被执行的代码的错误
            uuidDic['specUUIDS_' + index][item.specValue.value]
        }
      })
      item.uuid = buildUUID()
      tableDatas.value?.push(item)
      // const [object1, object2, object3] = specKeyParamList
      // if (object1) {
      //   const { specValue } = object1
      //   // @ts-ignore：无法被执行的代码的错误
      //   if (!dic1[specValue.value])
      //     // @ts-ignore：无法被执行的代码的错误
      //     dic1[specValue.value] = { index: null, length: 0 }
      //   // @ts-ignore：无法被执行的代码的错误
      //   if (dic1[specValue.value].index === null)
      //     // @ts-ignore：无法被执行的代码的错误
      //     dic1[specValue.value].index = index
      //   // @ts-ignore：无法被执行的代码的错误
      //   dic1[specValue.value].length += 1
      // }
      // if (object2 && object3) {
      //   const { specValue } = object2
      //   // @ts-ignore：无法被执行的代码的错误
      //   if (!dic2[specValue.value])
      //     // @ts-ignore：无法被执行的代码的错误
      //     dic2[specValue.value] = { index: null, length: 0 }
      //   // @ts-ignore：无法被执行的代码的错误
      //   if (dic2[specValue.value].index === null)
      //     // @ts-ignore：无法被执行的代码的错误
      //     dic2[specValue.value].index = index
      //   // @ts-ignore：无法被执行的代码的错误
      //   dic2[specValue.value].length += 1
      // }

      // 借第一次循环生成
      initSection(specKeyParamList)
    })
    // initSpanMergeDic(dic1, dic2, dic3)
  }
  function initSpanMergeDic(dic1: any, dic2?: any, dic3?: any) {
    Object.keys(dic1).forEach((key) => {
      const item = dic1[key]
      const dicKey = getKey(item.index, 0)
      // @ts-ignore：无法被执行的代码的错误
      spanMergeDic.value[dicKey] = [item.length, 1]
      for (let index = 1; index < item.length; index++) {
        const dicKey = getKey(item.index + 1, 0)
        // @ts-ignore：无法被执行的代码的错误
        spanMergeDic.value[dicKey] = [0, 0]
      }
    })
    dic2 &&
      Object.keys(dic2).forEach((key) => {
        const item = dic2[key]
        const dicKey = getKey(item.index, 1)
        // @ts-ignore：无法被执行的代码的错误
        spanMergeDic.value[dicKey] = [item.length, 1]
        for (let index = 1; index < item.length; index++) {
          const dicKey = getKey(item.index, 1)
          // @ts-ignore：无法被执行的代码的错误
          spanMergeDic.value[dicKey] = [0, 0]
        }
      })
  }
  // 通过后台数据生成secitonCell
  function initSection(spec: specKeyParamList[]) {
    const datas = sectionData.value
    const [dic1, dic2, dic3] = spec
    if (dic1) checkDic(dic1, 0)
    if (dic2) checkDic(dic2, 1)
    if (dic3) checkDic(dic3, 2)

    function checkDic(dic: any, index: number) {
      const { text, specValue } = dic
      // @ts-ignore：无法被执行的代码的错误
      datas[index].text = text
      // @ts-ignore：无法被执行的代码的错误
      const b = sectionData.value[index].value.find((item: specValue) => {
        return item.value === specValue.value
      })
      if (!b) sectionData.value[index]?.value.push(specValue)
    }
  }

  // 添加
  /**
   * 添加
   * @param dic 添加的节点
   * @param index 添加的层级
   */
  function addSectionUpdateTableDatas(
    dic: specValue,
    index: number,
    sectionTitle: string,
    level?: number
  ) {
    console.log('dic =' + JSON.stringify(dic))
    function updateSort() {
      tableDatas.value = sortWithDatas(
        tableDatas.value as specInfoParamList[],
        0,
        sectionLevel.value + 1
      )
    }
    // index = 0 添加第一节点 第二节点*第三节点的新增加数
    // index = 1 添加第二节点 会增加第三节点的行数
    // index = 2 添加第三节点 就增加第三节点的数。
    // TODO 排序算法， 先假装已经排序后进行节点的添加操作
    switch (index) {
      case 0:
        {
          const [spec0, spec1, spec2] = sectionData.value
          if (sectionLevel.value === 0) {
            const specInfo = newSpecInfoParamList([dic], [sectionTitle])
            tableDatas.value.push(specInfo)
            return
          } else if (sectionLevel.value === 1) {
            spec1?.value.forEach((item1: specValue) => {
              const specInfo = newSpecInfoParamList(
                [dic, item1],
                [sectionTitle, spec1.text]
              )
              tableDatas.value.push(specInfo)
            })
          } else if (sectionLevel.value === 2) {
            spec1?.value.forEach((item1: specValue) => {
              spec2?.value.forEach((item2: specValue) => {
                const specInfo = newSpecInfoParamList(
                  [dic, item1, item2],
                  [sectionTitle, spec1.text, spec2.text]
                )
                tableDatas.value.push(specInfo)
              })
            })
          }
        }
        updateSort()
        break
      case 1:
        {
          const [spec0, spec1, spec2] = sectionData.value
          if (spec1?.value.length === 1 && sectionLevel.value === 1) {
            tableDatas.value.forEach((item) => {
              const tmp: any = {
                text: sectionTitle,
                specValue: dic,
              }
              item?.specKeyParamList.push(tmp)
            })
          } else if (sectionLevel.value === 1) {
            spec0?.value.forEach((item0: specValue) => {
              const specInfo = newSpecInfoParamList(
                [item0, dic],
                [spec0.text, sectionTitle]
              )
              tableDatas.value.push(specInfo)
            })
          } else if (sectionLevel.value === 2) {
            spec0?.value.forEach((item0: specValue) => {
              spec2?.value.forEach((item2: specValue) => {
                const specInfo = newSpecInfoParamList(
                  [item0, dic, item2],
                  [spec0.text, sectionTitle, spec2.text]
                )
                tableDatas.value.push(specInfo)
              })
            })
          }
        }
        updateSort()
        break
      case 2:
        {
          const [spec0, spec1, spec2] = sectionData.value
          if (spec2?.value.length === 1) {
            tableDatas.value.forEach((item) => {
              const tmp: any = {
                text: sectionTitle,
                specValue: dic,
              }
              item?.specKeyParamList.push(tmp)
            })
          } else {
            // 二级变三级。。已经实例化的往数组里塞一级。未实例化的实例化即可。
            spec0?.value.forEach((item0: specValue) => {
              spec1?.value.forEach((item1: specValue) => {
                const specInfo = newSpecInfoParamList(
                  [item0, item1, dic],
                  [spec0.text, spec1.text, sectionTitle]
                )
                tableDatas.value.push(specInfo)
              })
            })
          }
        }
        updateSort()
        break
      default:
        break
    }
  }

  function editSectionUpdateTableDatas(
    dic: specValue,
    index: number,
    sectionTitle?: string
  ) {
    // @ts-ignore：无法被执行的代码的错误
    console.log('dic.uuid =' + dic.uuid)
    tableDatas.value.forEach((item) => {
      // @ts-ignore：无法被执行的代码的错误
      // @ts-ignore：无法被执行的代码的错误
      const b = item?.specKeyParamList[index].specValue.uuid === dic.uuid
      if (b && item) {
        item.specKeyParamList[index].specValue.value = dic.value
      }
    })
  }

  function newSpecInfoParamList(
    data: specValue[],
    sectionTitles: string[]
  ): specInfoParamList {
    const tmp: specInfoParamList = getNewSpec()
    const item: specKeyParamList[] = []
    for (let index = 0; index < data.length; index++) {
      const element = data[index]
      const sectionTitle = sectionTitles[index]
      const tmp = { text: sectionTitle, specValue: element }
      // @ts-ignore：无法被执行的代码的错误
      item.push(tmp)
    }
    tmp.specKeyParamList = item
    return tmp
  }
  /**
   * 排序方法
   */
  function sortWithDatas(
    data: specInfoParamList[],
    pointerIndex: number = 0,
    allLevel: number
  ): specInfoParamList[] {
    const item = data[pointerIndex]
    // 第一级相同
    const firstDatas: specInfoParamList[] = []
    // 第二级相同
    const secondDatas: specInfoParamList[] = []

    for (let index = pointerIndex + 1; index < data.length; index++) {
      const lastItem = data[index]
      const b = comparisonItem(item, lastItem, 1)
      if (b) {
        // 只有第一层相同且有三级时才需要比较第二级
        if (allLevel >= 2) {
          const b = comparisonItem(item, lastItem, 2)
          if (b) {
            secondDatas.push(lastItem)
          } else {
            firstDatas.push(lastItem)
          }
        } else {
          firstDatas.push(lastItem)
        }
      }
    }
    // 删掉 并插入到最新的
    if (secondDatas.length > 0) {
      pullAll(data, secondDatas)
      data.splice(pointerIndex + 1, 0, ...secondDatas)
    }
    // 删掉 并插入到最新的
    if (firstDatas.length > 0) {
      pullAll(data, firstDatas)
      data.splice(pointerIndex + secondDatas.length + 1, 0, ...firstDatas)
    }
    if (pointerIndex + 1 < data.length) {
      console.log('pointerIndex =' + pointerIndex)
      console.log('data =' + JSON.stringify(data))
      return sortWithDatas(data, pointerIndex + 1, allLevel)
    } else {
      // 循环完成了
      return data
    }
  }

  /**
   * 比对两个实体是否同一个属性
   * @param a 实体a
   * @param b 实体b
   * @param level 深入比较层级
   */
  function comparisonItem(
    a: specInfoParamList,
    b: specInfoParamList,
    level: number = 0,
    needNodeID?: number[]
  ): boolean {
    let isEqual = true
    for (let index = 0; index < level; index++) {
      const objectA: specValue = a.specKeyParamList[index].specValue
      const objectB: specValue = b.specKeyParamList[index].specValue
      if (objectA.value !== objectB.value) {
        isEqual = false
      }
    }
    return isEqual
  }
  // 商品规格要用
  // 清理datas
  function clearDatas() {
    tableDatas.value?.splice(0, tableDatas.value.length)
    sectionData.value = [
      { text: '', value: [] },
      { text: '', value: [] },
      { text: '', value: [] },
    ]
    // Object.assign(tableDatas, [])
  }

  function deteleTableCell(level: number, text: string) {
    // 1. 先判断删除的是不是最后一个规格
    // 2. 不是正常删除
    // 3. 是的话 清空
    const value = sectionData.value[level]?.value
    // 是最后一个规格 因为删除是即时删除，所以到这里 已经被删，所以判断是0长度
    if (value && value.length < 1) {
      tableDatas.value.forEach((item) => {
        item?.specKeyParamList.splice(level, 1)
      })
      // 非最后一排，需要后面的数组向前移动
      sectionData.value.splice(level, 1)
      sectionData.value.push({ text: '', value: [] })
      if (level === 0) {
        tableDatas.value = []
      }
      // if (level - 1 === sectionLevel.value) {
      //   tableDatas.value.forEach((item) => {
      //     item?.specKeyParamList.pop()
      //   })
      //   // @ts-ignore：无法被执行的代码的错误
      //   sectionData.value[level].text = ''
      // } else {
      //   tableDatas.value.forEach((item) => {
      //     item?.specKeyParamList.splice(level, 1)
      //   })
      //   // 非最后一排，需要后面的数组向前移动
      //   sectionData.value.splice(level, 1)
      //   // sectionData.value.push({ text: '', value: [] })
      // }
      // console.log('sectionData =' + JSON.stringify(sectionData.value))
    } else {
      console.log('test tmpDelete')
      const tmpDelete: any[] = []
      tableDatas.value.forEach((item) => {
        const b = item?.specKeyParamList[level].specValue.value === text
        if (b) {
          tmpDelete.push(item)
        }
      })
      pullAll(tableDatas.value, tmpDelete)
    }
  }

  // 修改section代码
  function editSectionTitle(text: string, index: number) {
    tableDatas.value.forEach((item: any) => {
      const e = item.specKeyParamList
      if (e.length > index) e[index].text = text
    })
  }

  // 打包要用到的数据
  function packNetData() {
    // 成本价
    // @ts-ignore：无法被执行的代码的错误
    let minCostPrice = 0
    // 库存
    let allNum = 0
    // 实际售价
    let minPrice = 0
    // 重量和零售价没有 怎么说？
    const tmpTableDatas = cloneDeep(tableDatas)
    const convertAfter = tmpTableDatas.value.map((item: any) => {
      const { costPrice, specKeyParamList, num, price } = item
      console.log('costPrice =' + typeof costPrice)
      // @ts-ignore：无法被执行的代码的错误
      if (!minCostPrice || costPrice < minCostPrice) minCostPrice = costPrice
      allNum += parseInt(num)
      if (!minPrice || costPrice < minPrice) minPrice = costPrice

      // 上面最大最小值判断完毕再乘
      if (item.costPrice) item.costPrice = parseFloat(item.costPrice) * 100
      if (item.price) item.price = parseFloat(item.price) * 100
      return item
    })
    return {
      costPrice: minCostPrice,
      num: allNum,
      price: minPrice,
      convertAfter,
    }
  }

  /**
   * skuid加载商品详情
   */
  function loadDataConverSubmitData(data: any) {
    const { specInfos, skus } = data
    function getSectionData(specValueList: any) {
      return specValueList.map((item: any, index: number) => {
        const { id, text, unit } = specInfos[index]
        return {
          id,
          text,
          unit,
          specValue: item,
        }
      })
    }
    return skus.map((item: any, index: number) => {
      const { costPrice, num, price, specBarCode, specCode, specValueList } =
        item
      return {
        costPrice: costPrice / 100,
        num,
        price: price / 100,
        specBarCode,
        specCode,
        specKeyParamList: getSectionData(specValueList),
      }
    })
  }

  return {
    tableDatas,
    initDatas,
    spanMergeDic,
    sectionData,
    addSectionUpdateTableDatas,
    editSectionUpdateTableDatas,
    deteleTableCell,
    editSectionTitle,
    clearDatas,
    packNetData,
    loadDataConverSubmitData,
  }
}
function getKey(a: number, b: number = 0): string {
  return `${a}-${b}`
}

function getNewSpec(): specInfoParamList {
  return {
    specKeyParamList: [],
    // @ts-ignore：无法被执行的代码的错误
    price: '',
    // @ts-ignore：无法被执行的代码的错误
    num: '',
    // @ts-ignore：无法被执行的代码的错误
    costPrice: '',
    specCode: '',
    specBarCode: '',
  }
}
